#ifndef CLS_EXAMPLE_H
#define CLS_EXAMPLE_H
#include <vector>
#include <string>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <algorithm>
#include "SortUtils.h"

#define AGE_MIN 1
#define AGE_MAX 100
#define HEIGTH_MIN 8
#define HEIGTH_MAX 200

class Human
{

private:
    std::uint8_t age = 0;
    std::string name = "";
    std::uint16_t heigth = 0;
    std::uint8_t count = 0;

public:
    std::uint8_t getAge()
    {
        return age;
    }
    void setAge(uint8_t age)
    {
        Human::age = age;
    }
    void setHeigth(uint8_t heigth)
    {
        Human::heigth = heigth;
    }
    void setName(std::string name);
    std::string getName()
    {
        return name;
    }
    uint8_t getHeigth()
    {
        return heigth;
    }
};

class Man
{
private:
    uint8_t age = 0;
    std::string name = "";
    uint16_t heigth = 0;
    uint32_t weigth = 0;
    uint8_t sex;
    uint8_t setupManData(size_t count);

public:
    Man(uint8_t age, uint16_t heigth, std::string name, uint8_t sex) : age(age), name(name), heigth(heigth), sex(sex)
    {
        weigth = age * heigth;
    }

    uint8_t getAge()
    {
        return age;
    }
    std::string getName()
    {
        return name;
    }
    uint8_t getHeigth()
    {
        return heigth;
    }
    uint8_t getSex()
    {
        return sex;
    }
    uint8_t getWeigth()
    {
        return weigth;
    }
    void setAge(uint8_t age)
    {
        Man::age = age;
    }
    void setName(std::string name)
    {
        Man::name = name;
    }
    void setHeigth(uint8_t heigth)
    {
        Man::heigth = heigth;
    }
    void setWeigth(uint8_t weigth)
    {
        Man::weigth = weigth;
    }
    void setSex(uint8_t sex)
    {
        Man::sex = sex;
    }
};
extern std::vector<std::shared_ptr<Human>> humans;
extern std::vector<std::shared_ptr<Man>> mans;

//about condition variable
extern bool humanReady;
extern bool humanProcessed;

extern bool manReady;
extern bool manProcessed;
extern std::mutex mx;
extern std::condition_variable cv;
//about condition variable end

uint8_t randAge();
uint8_t randHeigth();
uint8_t randAction(uint8_t max, uint8_t min);

//about human thread
void createHumanThread();
uint8_t doWorkHuman(size_t count);
static void *HumanWorkThread(void *data)
{
    return (void *)doWorkHuman((size_t)data);
}
uint8_t setupHumanData(size_t count);
//about human thread end

//about man thread
void createManThread();
uint8_t doWorkMan(size_t count);
static void *ManWorkThread(void *data)
{
    return (void *)doWorkMan((size_t)data);
}
uint8_t setupManData(size_t count);
//about man thread end

//about output
/**
 * @brief 从小到大排序
 * 
 * @param data1 
 * @param data2 
 * @return true 
 * @return false 
 */
bool compareS2L(const std::shared_ptr<Human> &data1, const std::shared_ptr<Human> &data2);

bool compareL2S(const std::shared_ptr<Human> &data1, const std::shared_ptr<Human> &data2);

void printValue(std::shared_ptr<Human> human);
uint8_t outputHuman();

uint8_t outpuMan();

#endif